using System;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;

namespace Hearthbuddy.Controls
{
	/// <summary>
	/// Time Picker as a control that lets the user select a specific time
	/// </summary>
	[TemplatePart(Name = "PART_Minutes", Type = typeof(TextBox))]
	[TemplatePart(Name = "PART_Hours", Type = typeof(TextBox))]
	[TemplatePart(Name = "PART_Seconds", Type = typeof(TextBox))]
	[TemplatePart(Name = "PART_DecrementTime", Type = typeof(ButtonBase))]
	[TemplatePart(Name = "PART_IncreaseTime", Type = typeof(ButtonBase))]
	public class TimePicker : Control
	{
		/// <summary>
		/// Helper class that contains methods that execute mathematical operations
		/// </summary>
		public static class MathUtil
		{
			/// <summary>
			/// Validates the string passed by parsing it as int and checking if it is inside the bounds specified 
			/// then the resulting int will be incremented/decremented
			/// </summary>
			/// <param name="num">The string to parse as int and increment/decrement</param>
			/// <param name="minValue">The min value for the bound checking</param>
			/// <param name="maxVal">The max value for the bounds checking</param>
			/// <param name="increment">Pass true to increment and false to decrement</param>
			/// <returns>Returns the new number incremented or decremeneted</returns>
			public static int IncrementDecrementNumber(string num, int minValue, int maxVal, bool increment)
			{
				int num2 = ValidateNumber(num, minValue, maxVal);
				if (increment)
				{
					return Math.Min(num2 + 1, maxVal);
				}
				return Math.Max(num2 - 1, 0);
			}

			/// <summary>
			/// Parses the number and makes sure that it is within the bounds specified
			/// </summary>
			/// <param name="newNum">The string to parse and validate</param>
			/// <param name="minValue">The min value for the bound checking</param>
			/// <param name="maxValue">The max value for the bound checking</param>
			/// <returns>Returns the int that was constructed from the string + bound checking</returns>
			public static int ValidateNumber(string newNum, int minValue, int maxValue)
			{
				if (!int.TryParse(newNum, out var result))
				{
					return 0;
				}
				return ValidateNumber(result, minValue, maxValue);
			}

			/// <summary>
			/// makes sure that the number is within the bounds specified
			/// </summary>
			/// <param name="newNum">The number to validate</param>
			/// <param name="minValue">The min value for the bound checking</param>
			/// <param name="maxValue">The max value for the bound checking</param>
			/// <returns>Returns the int that was constructed from the string + bound checking</returns>
			public static int ValidateNumber(int newNum, int minValue, int maxValue)
			{
				newNum = Math.Max(newNum, minValue);
				newNum = Math.Min(newNum, maxValue);
				return newNum;
			}
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class Class24
		{
			public static readonly Class24 Instance9 = new Class24();

			internal void method_0(DependencyObject dependencyObject_0, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs_0)
			{
				TimePicker obj = (TimePicker)dependencyObject_0;
				obj.int_3 = obj.MinTime.Hours;
				obj.int_4 = obj.MinTime.Minutes;
				obj.int_5 = obj.MinTime.Seconds;
				obj.CoerceValue(SelectedTimeProperty);
			}

			internal void method_1(DependencyObject dependencyObject_0, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs_0)
			{
				TimePicker obj = (TimePicker)dependencyObject_0;
				obj.int_0 = obj.MaxTime.Hours;
				obj.int_1 = obj.MaxTime.Minutes;
				obj.int_2 = obj.MaxTime.Seconds;
				obj.CoerceValue(SelectedTimeProperty);
			}

			internal void method_2(DependencyObject dependencyObject_0, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs_0)
			{
				TimePicker timePicker = (TimePicker)dependencyObject_0;
				int num = MathUtil.ValidateNumber(timePicker.SelectedHour, timePicker.int_3, timePicker.int_0);
				if (num != timePicker.SelectedHour)
				{
					timePicker.SelectedHour = num;
				}
				smethod_6(timePicker);
			}

			internal void method_3(DependencyObject dependencyObject_0, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs_0)
			{
				TimePicker timePicker = (TimePicker)dependencyObject_0;
				int num = MathUtil.ValidateNumber(timePicker.SelectedMinute, timePicker.int_4, timePicker.int_1);
				if (num != timePicker.SelectedMinute)
				{
					timePicker.SelectedMinute = num;
				}
				smethod_6(timePicker);
			}

			internal void method_4(DependencyObject dependencyObject_0, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs_0)
			{
				TimePicker timePicker = (TimePicker)dependencyObject_0;
				int num = MathUtil.ValidateNumber(timePicker.SelectedSecond, timePicker.int_5, timePicker.int_2);
				if (num != timePicker.SelectedSecond)
				{
					timePicker.SelectedSecond = num;
				}
				smethod_6(timePicker);
			}
		}

		private int int_0 = 23;

		private int int_1 = 59;

		private int int_2 = 59;

		private int int_3;

		private int int_4;

		private int int_5;

		private TextBox textBox_0;

		private TextBox textBox_1;

		private TextBox textBox_2;

		private TextBox textBox_3;

		/// <summary>
		/// Gets or sets the minimum time selected
		/// </summary>
		public static readonly DependencyProperty MinTimeProperty;

		/// <summary>
		/// Gets or sets the maximum time that can be selected
		/// </summary>
		public static readonly DependencyProperty MaxTimeProperty;

		/// <summary>
		/// Backing store for the selected timestamp 
		/// </summary>
		public static readonly DependencyProperty SelectedTimeProperty;

		/// <summary>
		/// Backing store for the selected hour
		/// </summary>
		public static readonly DependencyProperty SelectedHourProperty;

		/// <summary>
		/// Backing store for the selected minsutes
		/// </summary>
		public static readonly DependencyProperty SelectedMinuteProperty;

		/// <summary>
		/// Backing store for the selected second
		/// </summary>
		public static readonly DependencyProperty SelectedSecondProperty;

		/// <summary>
		///
		/// </summary>
		public static readonly RoutedEvent SelectedTimeChangedEvent;

		private bool bool_0;

		/// <summary>
		/// Gets or sets the minimum time that can be selected
		/// </summary>
		public TimeSpan MinTime
		{
			get
			{
				return (TimeSpan)GetValue(MinTimeProperty);
			}
			set
			{
				SetValue(MinTimeProperty, value);
			}
		}

		/// <summary>
		/// Gets or sets the maximum time that can be selected
		/// </summary>
		public TimeSpan MaxTime
		{
			get
			{
				return (TimeSpan)GetValue(MaxTimeProperty);
			}
			set
			{
				SetValue(MaxTimeProperty, value);
			}
		}

		/// <summary>
		/// Gets or sets the selected timestamp 
		/// </summary>
		public TimeSpan SelectedTime
		{
			get
			{
				return (TimeSpan)GetValue(SelectedTimeProperty);
			}
			set
			{
				SetValue(SelectedTimeProperty, value);
			}
		}

		/// <summary>
		/// Gets or sets the selected Hour
		/// </summary>
		public int SelectedHour
		{
			get
			{
				return (int)GetValue(SelectedHourProperty);
			}
			set
			{
				SetValue(SelectedHourProperty, value);
			}
		}

		/// <summary>
		/// Gets or sets the selected minutes
		/// </summary>
		public int SelectedMinute
		{
			get
			{
				return (int)GetValue(SelectedMinuteProperty);
			}
			set
			{
				SetValue(SelectedMinuteProperty, value);
			}
		}

		/// <summary>
		/// Gets or sets the selected second
		/// </summary>
		public int SelectedSecond
		{
			get
			{
				return (int)GetValue(SelectedSecondProperty);
			}
			set
			{
				SetValue(SelectedSecondProperty, value);
			}
		}

		public event TimeSelectedChangedEventHandler SelectedTimeChanged
		{
			add
			{
				AddHandler(SelectedTimeChangedEvent, value);
			}
			remove
			{
				RemoveHandler(SelectedTimeChangedEvent, value);
			}
		}

		private static object smethod_0(DependencyObject dependencyObject_0, object object_0)
		{
			TimePicker timePicker = (TimePicker)dependencyObject_0;
			TimeSpan timeSpan = (TimeSpan)object_0;
			if (timeSpan < timePicker.MinTime)
			{
				return timePicker.MinTime;
			}
			if (timeSpan > timePicker.MaxTime)
			{
				return timePicker.MaxTime;
			}
			return timeSpan;
		}

		private static void smethod_1(DependencyObject dependencyObject_0, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs_0)
		{
			TimePicker timePicker = (TimePicker)dependencyObject_0;
			TimeSpan timeSpan = (TimeSpan)dependencyPropertyChangedEventArgs_0.NewValue;
			TimeSpan timeSpan_ = (TimeSpan)dependencyPropertyChangedEventArgs_0.OldValue;
			if (!timePicker.bool_0)
			{
				timePicker.method_7();
				if (timePicker.SelectedHour != timeSpan.Hours)
				{
					timePicker.SelectedHour = timeSpan.Hours;
				}
				if (timePicker.SelectedMinute != timeSpan.Minutes)
				{
					timePicker.SelectedMinute = timeSpan.Minutes;
				}
				if (timePicker.SelectedSecond != timeSpan.Seconds)
				{
					timePicker.SelectedSecond = timeSpan.Seconds;
				}
				timePicker.method_8();
				timePicker.method_9(timePicker.SelectedTime, timeSpan_);
			}
		}

		/// <summary>
		/// Default constructor
		/// </summary>
		public TimePicker()
		{
			SelectedTime = DateTime.Now.TimeOfDay;
		}

		/// <summary>
		/// Static constructor
		/// </summary>
		static TimePicker()
		{
			MinTimeProperty = DependencyProperty.Register("MinTime", typeof(TimeSpan), typeof(TimePicker), new UIPropertyMetadata(TimeSpan.MinValue, delegate(DependencyObject dependencyObject_0, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs_0)
			{
				TimePicker obj2 = (TimePicker)dependencyObject_0;
				obj2.int_3 = obj2.MinTime.Hours;
				obj2.int_4 = obj2.MinTime.Minutes;
				obj2.int_5 = obj2.MinTime.Seconds;
				obj2.CoerceValue(SelectedTimeProperty);
			}));
			MaxTimeProperty = DependencyProperty.Register("MaxTime", typeof(TimeSpan), typeof(TimePicker), new UIPropertyMetadata(TimeSpan.MaxValue, delegate(DependencyObject dependencyObject_0, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs_0)
			{
				TimePicker obj = (TimePicker)dependencyObject_0;
				obj.int_0 = obj.MaxTime.Hours;
				obj.int_1 = obj.MaxTime.Minutes;
				obj.int_2 = obj.MaxTime.Seconds;
				obj.CoerceValue(SelectedTimeProperty);
			}));
			SelectedTimeProperty = DependencyProperty.Register("SelectedTime", typeof(TimeSpan), typeof(TimePicker), new UIPropertyMetadata(new TimeSpan(0, 0, 0), smethod_1, smethod_0));
			SelectedHourProperty = DependencyProperty.Register("SelectedHour", typeof(int), typeof(TimePicker), new UIPropertyMetadata(0, delegate(DependencyObject dependencyObject_0, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs_0)
			{
				TimePicker timePicker3 = (TimePicker)dependencyObject_0;
				int num3 = MathUtil.ValidateNumber(timePicker3.SelectedHour, timePicker3.int_3, timePicker3.int_0);
				if (num3 != timePicker3.SelectedHour)
				{
					timePicker3.SelectedHour = num3;
				}
				smethod_6(timePicker3);
			}));
			SelectedMinuteProperty = DependencyProperty.Register("SelectedMinute", typeof(int), typeof(TimePicker), new UIPropertyMetadata(0, delegate(DependencyObject dependencyObject_0, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs_0)
			{
				TimePicker timePicker2 = (TimePicker)dependencyObject_0;
				int num2 = MathUtil.ValidateNumber(timePicker2.SelectedMinute, timePicker2.int_4, timePicker2.int_1);
				if (num2 != timePicker2.SelectedMinute)
				{
					timePicker2.SelectedMinute = num2;
				}
				smethod_6(timePicker2);
			}));
			SelectedSecondProperty = DependencyProperty.Register("SelectedSecond", typeof(int), typeof(TimePicker), new UIPropertyMetadata(0, delegate(DependencyObject dependencyObject_0, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs_0)
			{
				TimePicker timePicker = (TimePicker)dependencyObject_0;
				int num = MathUtil.ValidateNumber(timePicker.SelectedSecond, timePicker.int_5, timePicker.int_2);
				if (num != timePicker.SelectedSecond)
				{
					timePicker.SelectedSecond = num;
				}
				smethod_6(timePicker);
			}));
			SelectedTimeChangedEvent = EventManager.RegisterRoutedEvent("SelectedTimeChanged", RoutingStrategy.Bubble, typeof(TimeSelectedChangedEventHandler), typeof(TimePicker));
			FrameworkElement.DefaultStyleKeyProperty.OverrideMetadata(typeof(TimePicker), new FrameworkPropertyMetadata(typeof(TimePicker)));
		}

		/// <summary>
		/// override to hook to the Control template elements
		/// </summary>
		public override void OnApplyTemplate()
		{
			textBox_0 = GetTemplateChild("PART_Hours") as TextBox;
			textBox_0.PreviewTextInput += textBox_0_PreviewTextInput;
			textBox_0.KeyUp += textBox_0_KeyUp;
			textBox_0.GotFocus += textBox_2_GotMouseCapture;
			textBox_0.GotMouseCapture += textBox_2_GotMouseCapture;
			textBox_1 = GetTemplateChild("PART_Minutes") as TextBox;
			textBox_1.PreviewTextInput += textBox_1_PreviewTextInput;
			textBox_1.KeyUp += textBox_1_KeyUp;
			textBox_1.GotFocus += textBox_2_GotMouseCapture;
			textBox_1.GotMouseCapture += textBox_2_GotMouseCapture;
			textBox_2 = GetTemplateChild("PART_Seconds") as TextBox;
			textBox_2.PreviewTextInput += textBox_2_PreviewTextInput;
			textBox_2.KeyUp += textBox_2_KeyUp;
			textBox_2.GotFocus += textBox_2_GotMouseCapture;
			textBox_2.GotMouseCapture += textBox_2_GotMouseCapture;
			(GetTemplateChild("PART_IncreaseTime") as ButtonBase).Click += method_2;
			(GetTemplateChild("PART_DecrementTime") as ButtonBase).Click += method_1;
		}

		private void textBox_2_GotMouseCapture(object sender, RoutedEventArgs e)
		{
			(textBox_3 = (TextBox)sender).SelectAll();
		}

		private void textBox_0_PreviewTextInput(object sender, TextCompositionEventArgs e)
		{
			smethod_5(textBox_0);
			string string_ = smethod_3(textBox_0, e.Text);
			method_4(string_);
			smethod_4(textBox_0, textBox_1);
			e.Handled = true;
		}

		private void textBox_1_PreviewTextInput(object sender, TextCompositionEventArgs e)
		{
			smethod_5(textBox_1);
			string string_ = smethod_3(textBox_1, e.Text);
			method_5(string_);
			smethod_4(textBox_1, textBox_2);
			e.Handled = true;
		}

		private void textBox_2_PreviewTextInput(object sender, TextCompositionEventArgs e)
		{
			smethod_5(textBox_2);
			string string_ = smethod_3(textBox_2, e.Text);
			method_6(string_);
			smethod_4(textBox_2, null);
			e.Handled = true;
		}

		private bool method_0(Key key_0)
		{
			if (key_0 == Key.Up)
			{
				method_3(bool_1: true);
			}
			else
			{
				if (key_0 != Key.Down)
				{
					return false;
				}
				method_3(bool_1: false);
			}
			return true;
		}

		private void textBox_0_KeyUp(object sender, KeyEventArgs e)
		{
			smethod_2(textBox_0, null, textBox_1, e.Key);
			if (!method_0(e.Key))
			{
				method_4(textBox_0.Text);
			}
		}

		private void textBox_1_KeyUp(object sender, KeyEventArgs e)
		{
			smethod_2(textBox_1, textBox_0, textBox_2, e.Key);
			if (!method_0(e.Key))
			{
				method_5(textBox_1.Text);
			}
		}

		private void textBox_2_KeyUp(object sender, KeyEventArgs e)
		{
			smethod_2(textBox_2, textBox_1, null, e.Key);
			if (!method_0(e.Key))
			{
				method_6(textBox_2.Text);
			}
		}

		private void method_1(object sender, RoutedEventArgs e)
		{
			method_3(bool_1: false);
		}

		private void method_2(object sender, RoutedEventArgs e)
		{
			method_3(bool_1: true);
		}

		private void method_3(bool bool_1)
		{
			if (textBox_0 == textBox_3)
			{
				SelectedHour = MathUtil.IncrementDecrementNumber(textBox_0.Text, int_3, int_0, bool_1);
			}
			else if (textBox_1 == textBox_3)
			{
				SelectedMinute = MathUtil.IncrementDecrementNumber(textBox_1.Text, int_4, int_1, bool_1);
			}
			else
			{
				SelectedSecond = MathUtil.IncrementDecrementNumber(textBox_2.Text, int_5, int_2, bool_1);
			}
		}

		private int method_4(string string_0)
		{
			return SelectedHour = MathUtil.ValidateNumber(string_0, int_3, int_0);
		}

		private int method_5(string string_0)
		{
			return SelectedMinute = MathUtil.ValidateNumber(string_0, int_4, int_1);
		}

		private int method_6(string string_0)
		{
			return SelectedSecond = MathUtil.ValidateNumber(string_0, int_5, int_2);
		}

		private static void smethod_2(TextBox textBox_4, TextBox textBox_5, TextBox textBox_6, Key key_0)
		{
			if (key_0 == Key.Left && textBox_5 != null && textBox_4.CaretIndex == 0)
			{
				textBox_5.Focus();
			}
			else if (key_0 == Key.Right && textBox_6 != null && textBox_4.CaretIndex == textBox_4.Text.Length)
			{
				textBox_6.Focus();
			}
		}

		private static string smethod_3(TextBox textBox_4, string string_0)
		{
			if (textBox_4.Text.Length == 2)
			{
				if (textBox_4.CaretIndex == 0)
				{
					return string_0 + textBox_4.Text[1];
				}
				return textBox_4.Text[0] + string_0;
			}
			if (textBox_4.CaretIndex != 0)
			{
				return textBox_4.Text + string_0;
			}
			return string_0 + textBox_4.Text;
		}

		private static void smethod_4(TextBox textBox_4, TextBox textBox_5)
		{
			if (textBox_4.CaretIndex == 1 && textBox_5 != null)
			{
				textBox_5.Focus();
			}
			else if (textBox_4.CaretIndex == 0)
			{
				textBox_4.CaretIndex++;
			}
		}

		private static void smethod_5(TextBox textBox_4)
		{
			if (textBox_4.SelectionLength > 0)
			{
				textBox_4.Text = textBox_4.Text.Remove(textBox_4.SelectionStart, textBox_4.SelectionLength);
			}
		}

		private static void smethod_6(TimePicker timePicker_0)
		{
			if (!timePicker_0.bool_0)
			{
				TimeSpan timeSpan = new TimeSpan(timePicker_0.SelectedHour, timePicker_0.SelectedMinute, timePicker_0.SelectedSecond);
				if (timePicker_0.SelectedTime != timeSpan)
				{
					timePicker_0.SelectedTime = timeSpan;
				}
			}
		}

		private void method_7()
		{
			bool_0 = true;
		}

		private void method_8()
		{
			bool_0 = false;
		}

		private void method_9(TimeSpan timeSpan_0, TimeSpan timeSpan_1)
		{
			TimeSelectedChangedRoutedEventArgs timeSelectedChangedRoutedEventArgs = new TimeSelectedChangedRoutedEventArgs(SelectedTimeChangedEvent);
			timeSelectedChangedRoutedEventArgs.NewTime = timeSpan_0;
			timeSelectedChangedRoutedEventArgs.OldTime = timeSpan_1;
			RaiseEvent(timeSelectedChangedRoutedEventArgs);
		}
	}
}
